﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace EfficientlyLazy.PhotoFramer.Entity
{
    public class SystemSettings
    {
        internal class SettingValue
        {
            public string Name { get; set; }
            public string OriginalValue { get; set; }
            public string NewValue { get; set; }
        }

        private readonly List<SettingValue> _values = new List<SettingValue>();

        //private readonly SortedDictionary<string, string> _settingValues = new SortedDictionary<string, string>();
        //private readonly SortedDictionary<string, string> _originalValues = new SortedDictionary<string, string>();

        public SystemSettings(IEnumerable<GlobalSetting> settings)
        {
            foreach (var setting in settings)
            {
                _values.Add(new SettingValue
                                {
                                    Name = setting.Name,
                                    OriginalValue = setting.Value,
                                    NewValue = setting.Value
                                });

                //_settingValues.Add(setting.Name, setting.Value);
                //_originalValues.Add(setting.Name, setting.Value);
            }
        }

        [Category("Paths")]
        [DisplayName("Photo Frame Root")]
        [Description("")]
        [EditorAttribute(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
        public string PhotoFrameRoot
        {
            get { return Get(GlobalSettings.PhotoFrameRoot); }
            set { Set(GlobalSettings.PhotoFrameRoot, value); }
        }

        [Category("Paths")]
        [DisplayName("Camera Root")]
        [Description("")]
        [EditorAttribute(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
        public string CameraRoot
        {
            get { return Get(GlobalSettings.CameraRoot); }
            set { Set(GlobalSettings.CameraRoot, value); }
        }

        [Category("Paths")]
        [DisplayName("Local Image Root")]
        [Description("")]
        [EditorAttribute(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
        public string LocalImageRoot
        {
            get { return Get(GlobalSettings.LocalImageRoot); }
            set { Set(GlobalSettings.LocalImageRoot, value); }
        }

        private T Get<T>(GlobalSettingName<T> settingName)
        {
            var setting = _values.Where(x => x.Name == settingName.Name).FirstOrDefault();

            if (setting == null)
            {
                _values.Add(new SettingValue
                                {
                                    Name = settingName.Name,
                                    NewValue = settingName.Default.ToString(),
                                    OriginalValue = settingName.Default.ToString()
                                });

                return settingName.Default;
            }

            return (T)Convert.ChangeType(setting.NewValue, typeof(T));
        }

        private void Set<T>(GlobalSettingName<T> settingName, T value)
        {
            var setting = _values.Where(x => x.Name == settingName.Name).FirstOrDefault();

            if (setting == null)
            {
                _values.Add(new SettingValue
                                {
                                    Name = settingName.Name,
                                    NewValue = value.ToString(),
                                    OriginalValue = default(T).ToString()
                                });

                return;
            }

            setting.NewValue = value.ToString();
        }

        public bool HasChanges()
        {
            return _values.Any(setting => !setting.NewValue.Equals(setting.OriginalValue));
        }

        public string GetChangeMessage()
        {
            var sb = new StringBuilder();

            var changed = _values.Where(setting => !setting.NewValue.Equals(setting.OriginalValue));

            foreach (var change in changed)
            {
                var fromValue = string.IsNullOrEmpty(change.OriginalValue) ? "<blank>" : change.OriginalValue;
                var toValue = string.IsNullOrEmpty(change.NewValue) ? "<blank>" : change.NewValue;

                sb.AppendFormat("{0} changed from {1} to {2}\r\n", change.Name, fromValue, toValue);
            }

            return sb.ToString();
        }

        internal void Revert()
        {
            foreach (var sv in _values)
            {
                sv.NewValue = sv.OriginalValue;
            }
        }
        
        internal IList<SettingValue> GetChanges()
        {
            return _values.Where(setting => !setting.NewValue.Equals(setting.OriginalValue)).ToList();
        }
    }
}
